package com.siha_back.client;


import com.google.gson.Gson;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;


@SpringBootApplication
public class DeepSeekClient {


    //加载配置文件，读取key和url
    private static String API_KEY;
    private static String API_URL;


    private static final Map<String, List<Message>> conversationHistory = new ConcurrentHashMap<>();

    static {
        Properties properties = new Properties();
        try {
            InputStream is = DeepSeekClient.class.getResourceAsStream("/config.properties");
            properties.load(is);
            API_KEY = properties.getProperty("key");
            API_URL = properties.getProperty("url");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //消息类Message
    static class Message {
        private String role;
        private String content;

        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }

        public String getContent() {
            return content;
        }
    }

    //请求体类
    static class ChatRequest {
        private String model;
        private List<Message> messages;
        private double temperature;
        private int max_tokens;

        public ChatRequest(String model, List<Message> messages, double temperature, int max_tokens) {
            this.model = model;
            this.messages = messages;
            this.temperature = temperature;
            this.max_tokens = max_tokens;
        }
    }

    //响应体类
    static class ChatResponse {
        private List<Choice> choices;

        public List<Choice> getChoices() {
            return choices;
        }

        static class Choice {
            private Message message;

            public Message getMessage() {
                return message;
            }
        }
    }

    /**
     * 单轮对话（不保留上下文）
     */
    public static String singleTurnAsk(String content) {
        return ask(content, null); // 传入null表示不保留历史
    }

    /**
     * 多轮对话（保留上下文）
     * @param sessionId 会话ID，相同ID会保留对话历史
     */
    public static String multiTurnAsk(String content, String sessionId) {
        return ask(content, sessionId);
    }

    /**
     * 清除指定会话的历史记录
     */
    public static void clearConversation(String sessionId) {
        conversationHistory.remove(sessionId);
    }

    /**
     * 核心请求方法
     */
    public static String ask(String content, String sessionId) {
        List<Message> messages = new ArrayList<>();

        // 多轮对话处理
        if (sessionId != null) {
            // 获取或创建历史记录
            List<Message> history = conversationHistory.computeIfAbsent(
                    sessionId, k -> new ArrayList<>());

            // 添加历史消息（最多保留10轮对话）
            if (history.size() > 20) {
                history = history.subList(history.size() - 20, history.size());
                conversationHistory.put(sessionId, new ArrayList<>(history));
            }

            messages.addAll(history);
        }

        // 添加用户新消息
        Message userMessage = new Message("user", content);
        messages.add(userMessage);

        // 构建请求体
        ChatRequest requestBody = new ChatRequest(
                "deepseek-chat",
                messages,
                0.7,
                1000
        );

        System.out.println(">>>正在提交问题...");
        long startTime = System.currentTimeMillis();

        // 发送请求
        String response = sendRequest(requestBody);

        // 多轮对话保存响应
        if (sessionId != null) {
            conversationHistory.get(sessionId).add(userMessage);
            conversationHistory.get(sessionId).add(new Message("assistant", response));
        }

        long endTime = System.currentTimeMillis();
        System.out.printf("思考用时：%.2f秒%n", (endTime - startTime) / 1000.0);
        return response;
    }
    //发送请求体的方法
    private static String sendRequest(ChatRequest requestBody) {
        HttpClient client = HttpClient.newHttpClient();
        Gson gson = new Gson();
        // 将 ChatRequest 对象中封装的数据转为 JSON 格式
        String requestBodyJson = gson.toJson(requestBody);

        try {
            // 构建请求对象 并指定请求头内容格式及身份验证的key
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(API_URL))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + API_KEY)
                    // 将JSON格式的字符串封装为 BodyPublishers 对象
                    .POST(HttpRequest.BodyPublishers.ofString(requestBodyJson))
                    .build();  // 构建请求对象
            System.out.println(">>>已提交问题，正在思考中......");
            // 发送请求并获取响应对象
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            // 如果响应状态码为成功 200
            if (response.statusCode() == 200) {
                //System.out.println("响应体：");
                //System.out.println(response.body());
                // 解析响应 把响应体中的json字符串转为 ChatResponse 对象
                ChatResponse chatResponse = gson.fromJson(response.body(), ChatResponse.class);
                // 按 JSON 格式的方式 从自定义的ChatResponse对象中逐级取出最终的响应对象
                return chatResponse.getChoices().get(0).getMessage().getContent();

            }else
                return "请求失败,状态码:"+response.statusCode()+"响应:"+response.body();
        }catch (Exception e){
            e.printStackTrace();
            return "请求异常:"+e.getMessage();
        }
    }
     //逐字打印字符串，模拟打字的效果
    public class TypewriterEffect {
        public static void printWord(String text, int delay) {
            //System.out.println("正在打印.....\n"+text);
            //逐字输出text的内容
            for (char c : text.toCharArray()) {
                System.out.print(c);
                try {
                    Thread.sleep(delay); // 延迟
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(); // 换行
        }
    }

}
